<%@ page import="jakarta.servlet.http.HttpSession" %>
<%@ page import="jakarta.servlet.http.Cookie" %>
<%@ page import="jakarta.servlet.http.Part" %>
<%@ page import="java.util.*" %>
<%@ page import="java.security.Principal" %>
<%@ page import="jakarta.servlet.ServletInputStream" %>
<%@ page import="java.io.BufferedReader" %>
<%@ page import="jakarta.servlet.RequestDispatcher" %>
<%@ page import="jakarta.servlet.ServletContext" %>
<%@ page import="jakarta.servlet.http.HttpServletRequest" %>
<%@ page import="jakarta.servlet.DispatcherType" %>
<%@ page import="sun.misc.CompoundEnumeration" %>
<%@ page import="java.net.URLDecoder" %><%--
  Created by IntelliJ IDEA.
  User: 刘明福
  Date: 2022/9/19
  Time: 17:30
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
<%
    //在请求会话里面存放两个键值对
    request.setAttribute("key1", "张三");
    request.setAttribute("key2", "李四");

    /**
     * 用于获取客户端对当前请求进行身份验证的方法的名称。它返回一个字符串，表示身份验证方法的名称，或者如果请求未经过身份验证，则返回null。
     * getAuthType()方法返回的身份验证方法的名称通常是由服务器提供的，并且取决于服务器的配置和实现。
     * 常见的身份验证方法包括BASIC、DIGEST、FORM等。如果请求未经过身份验证，则返回null。
     */
    String authType = request.getAuthType();
    //获取异步上下文对象（AsyncContext）。异步上下文对象用于支持异步请求和响应处理
//    jakarta.servlet.AsyncContext asyncContext = request.getAsyncContext();
    //获取请求中所有属性的名称。它返回一个枚举（Enumeration）对象，其中包含请求中所有属性的名称
    Enumeration<String> attributeNames = request.getAttributeNames();
    //获取请求中指定属性的值。它接受一个字符串参数，表示要获取的属性的名称，并返回该属性的值。
    String attribute1 = (String) request.getAttribute("key1");
    String attribute2 = (String) request.getAttribute("key2");

    //获取请求类的class对象
    Class<? extends HttpServletRequest> aClass = request.getClass();
    //获取当前Web应用程序的上下文路径
    String contextPath = request.getContextPath();
    //用于获取服务器解析请求时确定的内容类型。
    String contentType = request.getContentType();
    //用于获取当前请求的字符编码。它返回一个字符串，表示当前请求使用的字符编码，或者如果字符编码未指定，则返回null。
    String characterEncoding = request.getCharacterEncoding();
    //它返回一个Cookie数组，其中包含当前请求的所有Cookie对象。
    Cookie[] cookies = request.getCookies();
    //获取请求正文的长度。它返回一个整数，表示请求正文的长度（以字节为单位）。
    int contentLength = request.getContentLength();
    //用于获取请求正文的长度。它返回一个长整型，表示请求正文的长度（以字节为单位）。
    long contentLengthLong = request.getContentLengthLong();

    //获取请求的调度器类型。它返回一个DispatcherType枚举对象，表示请求的调度器类型，可以是REQUEST、FORWARD、INCLUDE、ASYNC或ERROR
    DispatcherType dispatcherType = request.getDispatcherType();
    //用于从HTTP请求头中获取指定名称的日期值。它接受一个字符串参数，表示要获取的HTTP请求头的名称，然后返回该请求头的日期值。
    long dateHeader = request.getDateHeader("Last-Modified");


    //返回一个枚举（Enumeration）对象，该对象包含所有HTTP请求头的名称。可以通过遍历该枚举对象来获取每个请求头的名称。
    Enumeration<String> headerNames = request.getHeaderNames();
    //获取指定的请求头值
    String header = request.getHeader("Accept-Encoding");
    //用于获取客户端发送请求时指定的内容类型
    String header_ContentType = request.getHeader("Content-Type");
    //返回一个枚举（Enumeration）对象，该对象包含指定HTTP请求头的所有值。可以通过遍历该枚举对象来获取每个请求头的值。有的请求头可以同时存在多个值
    Enumeration<String> headers = request.getHeaders("User-Agent");
    //获取请求的HttpServletMapping对象。HttpServletMapping对象表示请求的URL与Servlet的映射关系。
    HttpServletMapping httpServletMapping = request.getHttpServletMapping();


    //获取一个请求头的整数值
    int intHeader_Content_Length = request.getIntHeader("Content-Length");
    //用于获取请求的输入流。它返回一个ServletInputStream对象，可以用于读取请求中的数据。例如：读取post请求body中的数据
    ServletInputStream inputStream = request.getInputStream();


    //获取服务器的IP地址。这个IP地址是服务器上网络接口的本地地址。
    String localAddr = request.getLocalAddr();
    //获取服务器的主机名。这个主机名是服务器上网络接口的本地名称。
    String localName = request.getLocalName();
    //返回服务器接收客户端连接的本地端口号。
    int localPort = request.getLocalPort();
    //用于获取客户端的首选语言环境。它返回一个Locale对象，表示客户端的首选语言环境。
    Locale locale = request.getLocale();
    //用于获取客户端支持的所有语言环境。它返回一个枚举（Enumeration）对象，其中包含客户端支持的所有语言环境。
    Enumeration<Locale> locales = request.getLocales();


    //用于获取HTTP请求的方法。它返回一个字符串，表示HTTP请求的方法，例如GET、POST、PUT等。
    String method = request.getMethod();


    /**
     * 用于获取HTTP请求中的指定部分,通常用于处理文件上传等场景。
     * file就是上传文件对应的key，上传的文件二进制流会被封装进Part对象里面
     * 在使用getPart()方法之前，需要确保请求中包含指定的部分，否则可能会返回null。
     * 此外，还需要注意处理文件上传时的文件名编码、文件大小限制等问题，以确保安全和正确处理上传的文件。
     */
//    Part part = request.getPart("file");
    //获取HTTP请求中的所有部分，例如上传的文件。它返回一个Collection对象，其中包含表示每个部分的Part对象。
//    Collection<Part> parts = request.getParts();
    //getPathTranslated()方法返回一个字符串，表示对应请求路径在服务器文件系统上的真实路径。它会将相对路径转换为服务器上的绝对路径。
    String pathTranslated = request.getPathTranslated();
    //用于获取HTTP请求的协议。它返回一个字符串，表示HTTP请求的协议，例如HTTP/1.1
    String protocol = request.getProtocol();
    //用于获取请求参数的映射。它返回一个Map对象，其中包含请求参数的名称和对应的值。
    Map<String, String[]> parameterMap = request.getParameterMap();
    //用于获取请求参数的名称。它返回一个枚举（Enumeration）对象，其中包含请求参数的名称。
    Enumeration<String> parameterNames = request.getParameterNames();
    //用于获取请求参数的值。它接受一个字符串参数，表示要获取的参数的名称，然后返回一个字符串数组，包含该参数的所有值。
    String[] parameterValues = request.getParameterValues("car");
    //用于获取请求的附加路径信息。它返回一个字符串，表示请求的附加路径信息。
    String pathInfo = request.getPathInfo();
    //用于获取请求参数的值。它接受一个字符串参数，表示要获取的参数的名称，然后返回该参数的值。
    String parameter_car = request.getParameter("car");
    //用于获取请求参数的值。它接受一个字符串参数，表示要获取的参数的名称，然后返回该参数的值。
    String parameter_name = request.getParameter("name");


    //获取路径uri后面拼接的所有参数键值对，也称作请求的查询字符串，也就是?后面拼接的所有参数
    String queryString = request.getQueryString();


    //用于获取与当前请求关联的已验证用户的名称。它返回一个字符串，表示发起请求的用户的名称，或者如果用户未经过身份验证，则返回null。
    String remoteUser = request.getRemoteUser();
    //用于获取客户端请求中所包含的会话ID。它返回一个字符串，表示会话ID，或者如果请求中不包含会话ID，则返回null。
    String requestedSessionId = request.getRequestedSessionId();
    //将相对路径转为服务器上面的绝对路径
    String realPath = request.getRealPath("/msdev/dongYaBank/request_Test.jsp");
    //返回客户端的IP地址，即客户端的网络地址
    String remoteAddr = request.getRemoteAddr();
    //返回客户端的主机名，即客户端的计算机名。
    String remoteHost = request.getRemoteHost();
    //返回客户端连接的端口号。
    int remotePort = request.getRemotePort();
    //用于获取请求的URI（统一资源标识符）。它返回一个字符串，表示请求的URI。
    String requestURI = request.getRequestURI();
    //用于获取请求的URL（统一资源定位器）。它返回一个StringBuffer对象，表示请求的URL。
    // URL是URI的子集，uri只是端口后面的路径且不包括任何参数，url包括协议后面的一切
    StringBuffer requestURL = request.getRequestURL();
    //用于获取请求的字符输入流。它返回一个BufferedReader对象，可以用于读取请求中的字符数据。
//    BufferedReader reader = request.getReader();
    //用于获取请求的转发器（RequestDispatcher）。转发器用于将请求转发到其他资源，例如Servlet、JSP或其他Web组件。
    RequestDispatcher requestDispatcher = request.getRequestDispatcher("/index.html");


    //获取当前请求的session会话
    HttpSession session_1 = request.getSession();
    //用于获取Servlet上下文对象（ServletContext）。Servlet上下文对象是在Web应用程序级别共享的对象，用于在不同的Servlet和JSP之间共享数据和资源。
    ServletContext servletContext = request.getServletContext();
    //用于获取服务器的主机名（hostname）。它返回一个字符串，表示服务器的主机名。
    String serverName = request.getServerName();
    //返回服务器运行的端口号。
    int serverPort = request.getServerPort();
    //用于获取请求的协议方案（scheme）。它返回一个字符串，表示请求的协议方案，例如http、https等。
    String scheme = request.getScheme();
    //用于获取请求的Servlet路径。它返回一个字符串，表示请求的Servlet路径。
    String servletPath = request.getServletPath();

    //用于获取HTTP请求的尾部字段（Trailer Fields）。尾部字段是在HTTP请求的尾部包含的一些附加字段，用于提供额外的请求信息。
    //尾部字段通常在使用Transfer-Encoding为chunked的情况下使用。
    Map<String, String> trailerFields = request.getTrailerFields();
    //用于获取HTTP请求的用户主体（User Principal）。用户主体表示当前请求的用户身份信息，通常用于进行身份验证和授权。
    // 它返回一个Principal对象，表示用户主体。
    Principal userPrincipal = request.getUserPrincipal();

%>
authType=：<%=authType%></br>
<%--asyncContext=：<%=asyncContext.toString()%></br>--%>
attributeNames=：<%=getEnumerationList(attributeNames,String.class)%></br>
attribute1=：<%=attribute1%></br>
attribute2=：<%=attribute2%></br>
aClass=：<%=aClass%></br>
contextPath=：<%=contextPath%></br>
contentType=：<%=contentType%></br>
characterEncoding=：<%=characterEncoding%></br>
cookies=：<%=printCookies(cookies)%></br>
contentLength=：<%=contentLength%></br>
contentLengthLong=：<%=contentLengthLong%></br>
dispatcherType=：<%=dispatcherType%></br>
dateHeader=：<%=dateHeader%></br>
headerNames=：<%=getEnumerationList(headerNames,String.class)%></br>
header=：<%=header%></br>
header_ContentType=：<%=header_ContentType%></br>
headers=：<%=getEnumerationList(headers,String.class)%></br>
httpServletMapping=：<%=printHttpServletMapping(httpServletMapping)%></br>
intHeader_Content_Length=：<%=intHeader_Content_Length%></br>
inputStream=：<%=inputStream%></br>
localAddr=：<%=localAddr%></br>
localName=：<%=localName%></br>
localPort=：<%=localPort%></br>
locale=：<%=locale%></br>
locales=：<%=getEnumerationList(locales,Locale.class)%></br>
method=：<%=method%></br>
<%--part=：<%=part%></br>--%>
<%--parts=：<%=parts%></br>--%>
pathTranslated=：<%=pathTranslated%></br>
protocol=：<%=protocol%></br>
parameterMap=：<%=printParameterMap(parameterMap)%></br>
parameterNames=：<%=getEnumerationList(parameterNames,String.class)%></br>
parameterValues=：<%=Arrays.toString(parameterValues)%></br>
pathInfo=：<%=pathInfo%></br>
parameter_car=：<%=parameter_car%></br>
parameter_name=：<%=parameter_name%></br>
queryString=：<%=URLDecoder.decode(queryString)%></br>
remoteUser=：<%=remoteUser%></br>
requestedSessionId=：<%=requestedSessionId%></br>
realPath=：<%=realPath%></br>
remoteAddr=：<%=remoteAddr%></br>
remoteHost=：<%=remoteHost%></br>
remotePort=：<%=remotePort%></br>
requestURI=：<%=requestURI%></br>
requestURL=：<%=requestURL%></br>
<%--reader=：<%=reader%></br>--%>
requestDispatcher=：<%=requestDispatcher%></br>
session_1=：<%=session_1%></br>
servletContext=：<%=servletContext%></br>
serverName=：<%=serverName%></br>
serverPort=：<%=serverPort%></br>
scheme=：<%=scheme%></br>
servletPath=：<%=servletPath%></br>
trailerFields=：<%=trailerFields%></br>
userPrincipal=：<%=userPrincipal%></br>


<%!


    /**
     * 打印parameterMap
     *
     * @param parameterMap 路径携带的参数键值对
     * @return void
     * @author LiuMingFu
     * @date 2023/10/15
     */
    public List<Map<String, Object>> printParameterMap(Map<String, String[]> parameterMap) {
        List<Map<String, Object>> resultData = new LinkedList<>();
        for (Map.Entry<String, String[]> stringEntry : parameterMap.entrySet()) {
            Map<String,Object> one = new LinkedHashMap<>();
            one.put("key",stringEntry.getKey());
            one.put("value",Arrays.toString(stringEntry.getValue()));
            one.put("class",stringEntry.getClass());
            resultData.add(one);
        }


        return resultData;
    }



    /**
     * 打印httpServletMapping
     *
     * @param httpServletMapping servlet映射对象
     * @return void
     * @author LiuMingFu
     * @date 2023/10/15
     */
    public Map<String, Object> printHttpServletMapping(HttpServletMapping httpServletMapping) {
        Map<String,Object> resultData = new HashMap<>();
        resultData.put("matchValue",httpServletMapping.getMatchValue());
        resultData.put("servletName",httpServletMapping.getServletName());
        resultData.put("pattern",httpServletMapping.getPattern());
        resultData.put("class",httpServletMapping.getClass());
        resultData.put("mappingMatch",httpServletMapping.getMappingMatch());

        return resultData;
    }


    /**
     * 遍历打印cookie数组
     *
     * @param cookies cookie数组
     * @return void
     * @author LiuMingFu
     * @date 2023/10/15
     */
    public List<Map<String, Object>> printCookies(Cookie[] cookies) {
        List<Map<String, Object>> resultData = new LinkedList<>();
        for (Cookie cookie : cookies) {
            Map<String, Object> map = new HashMap<>();
            map.put("name", cookie.getName());
            map.put("value", cookie.getValue());
            map.put("comment", cookie.getComment());
            map.put("domain", cookie.getDomain());
            map.put("path", cookie.getPath());
            map.put("maxAge", cookie.getMaxAge());
            map.put("secure", cookie.getSecure());
            map.put("class", cookie.getClass());
            map.put("version", cookie.getVersion());

            resultData.add(map);
        }

        return resultData;
    }



    public <T> List<T> getEnumerationList(Enumeration<T> parameterNames, Class<T> targetType) {
        List<T> resultData = new LinkedList<>();
        while (parameterNames.hasMoreElements()) {
            //获取下一个元素
            Object element = parameterNames.nextElement();
            if (targetType.isInstance(element)) {
                resultData.add(targetType.cast(element));
            }
        }
        return resultData;
    }


%>
</body>
</html>
